package com.handpay.framework.upcard;

import java.util.LinkedHashMap;
import java.util.Vector;

import android.text.TextUtils;

import com.handpay.zztong.hp.config.UPConfig;
import com.handpay.zztong.hp.log.HPLog;

public class UPXMLReqComposer {
	private static String xmlFormatBankList = "<?xml version=\"1.0\" encoding=\"utf-8\"?><cupMobile application=\"UPCards\" version=\"1.01\"><transaction type=\"BillEnquiry.APReq\"><submitTime>%s</submitTime><cardSerialNumber>%s</cardSerialNumber><serviceInfo>%s</serviceInfo><SpId>%s</SpId></transaction><securityChipTp>%s</securityChipTp><mac>%s</mac></cupMobile>";
	private static String xmlFormatBalanceFormate1 = "<?xml version=\"1.0\" encoding=\"utf-8\"?><cupMobile application=\"UPCards\" version=\"1.01\"><transaction type=\"BalanceEnquiry.APReq\"><submitTime>%s</submitTime><accountNumber1>%s</accountNumber1><pin>%s</pin>";
	private static String xmlFormatBalanceFormate2 = "<cardSerialNumber>%s</cardSerialNumber><dynamicKeyData>%s</dynamicKeyData><SpId>%s</SpId></transaction><securityChipTp>%s</securityChipTp><mac>%s</mac></cupMobile>";
	/**
	 * 直接访问银联查询刷卡器，交易过的卡号列表报文拼接
	 * 
	 * @param time
	 * @param csn
	 * @param serviceInfo
	 * @param
	 * @param mac
	 * @return
	 */
	public static String packetBankListToUp(String time, String csn, String serviceInfo, String mac) {
		// 拼接报文格式
		String requestXml = String.format(xmlFormatBankList, time, csn,
				serviceInfo, UPConfig.SPID, UPConfig.SECURITYCHIPTP, mac);
		return requestXml;
	}
	/**
	 * 直接访问银联查询余额，所需要的报文拼接
	 * 
	 * @param time
	 * @param encAccount
	 * @param encPin
	 * @param encTrack2
	 * @param csn
	 * @param tkey
	 * @param mac
	 * @return
	 */
	public static String xmlBalanceReq(String time, String encAccount, String encPin,
			String encTrack2, String csn, String tkey, String mac)
	{
		// 拼接报文格式
		String requestXml = String.format(xmlFormatBalanceFormate1, time, encAccount, encPin);
		if (encTrack2 != null && encTrack2.length() > 0)
		{
			requestXml += String.format("<track2Data>%s</track2Data>",
					encTrack2);
		}
		requestXml += String.format(xmlFormatBalanceFormate2, csn, tkey, UPConfig.SPID, UPConfig.SECURITYCHIPTP, mac);
		return requestXml;
	}
	public static String xmlPurchaseAdvice(String time,String merchantId,String merchantName,String merchantCountry,String terminalId,String orderId,String transAmount,String encAccount, String encPin,
			String encTrack2, String csn, String tkey,String icNumber,String DCData ,String mac ,String expireDate){
	    String xmlFormatPurchaseAdviceFormate1 ="<?xml version=\"1.0\" encoding=\"utf-8\"?><cupMobile application=\"UPCards\" version=\"1.01\"><transaction type=\"%s.APReq\"><submitTime>%s</submitTime>";
		String xmlFormatPurchaseAdviceFormate2 ="<dynamicKeyData>%s</dynamicKeyData><SpId>%s</SpId><SysProvide>%s</SysProvide></transaction><securityChipTp>%s</securityChipTp><mac>%s</mac></cupMobile>";
		xmlFormatPurchaseAdviceFormate1 = String.format(xmlFormatPurchaseAdviceFormate1, "PurchaseAdvice", time);
		xmlFormatPurchaseAdviceFormate1 += String.format("<merchant id=\"%s\" name=\"%s\" country=\"%s\" />",
				merchantId , merchantName.length()>0? merchantName: "瀚银",	merchantCountry.length() > 0 ? merchantCountry: "156");
		xmlFormatPurchaseAdviceFormate1 += String
				.format("<terminal id=\"%s\" />", terminalId);
		xmlFormatPurchaseAdviceFormate1 += String.format("<order id=\"%s\" />",orderId);
		xmlFormatPurchaseAdviceFormate1 += String.format("<transAmount>%s</transAmount><accountNumber1>%s</accountNumber1><pin>%s</pin>",
				 transAmount, encAccount,	encPin);
		xmlFormatPurchaseAdviceFormate1 += String.format("<track2Data>%s</track2Data>",
				encTrack2);
		xmlFormatPurchaseAdviceFormate1 += String.format("<cardSerialNumber>%s</cardSerialNumber>",
				csn);
		if(icNumber !=null){
			xmlFormatPurchaseAdviceFormate1+=String.format("<ICNumber>%s</ICNumber>",icNumber);
		}
		if(DCData != null){
			xmlFormatPurchaseAdviceFormate1+=String.format("<DCData>%s</DCData>",DCData);
		}
//解决话费充值失败问题  expireDate不需要
//		if(!TextUtils.isEmpty(expireDate)){
//			xmlFormatPurchaseAdviceFormate1+=String.format("<expireDate>%s</expireDate>",expireDate);
//		}
		xmlFormatPurchaseAdviceFormate1 += String.format(xmlFormatPurchaseAdviceFormate2, tkey,UPConfig.SPID,
				"10022900", UPConfig.SECURITYCHIPTP,mac);
		return xmlFormatPurchaseAdviceFormate1;
	}
	
    public static String getPlainMac(LinkedHashMap<Integer, String> map)
    {
        if (map == null || map.isEmpty()) {
            return null;
        }
        try
        {
            // 1:// 支付应用名称cupMobile:application
            // 2:// 版本号cupMobile:version
            // 3:// 交易类型cupMobile.transaction:type
            // (MAC)4:// 交易提交时间cupMobile.transaction.submitTime
            // (13,MAC)5:// 商户代码cupMobile.transaction.merchant:id
            // 6:// 商户名称cupMobile.transaction.merchant:name
            // 7:// 商户国家代码cupMobile.transaction.merchant:country
            // (13,MAC)8:// 子商户/终端代码cupMobile.transaction.terminal:id
            // (13,MAC)9:// 订单号cupMobile.transaction.order:id
            // (MAC)10:// 清算日期cupMobile.transaction.settleDate
            // (13,MAC)11:// 交易金额cupMobile.transaction.transAmount
            // (13,MAC)12:// 交易币种cupMobile.transaction.transAmount:currency
            // (13,MAC)13:// 扣账金额cupMobile.transaction.billAmount
            // (13,MAC)14:// 扣账币种cupMobile.transaction.billAmount:currency
            // (13,MAC)15:// 扣账汇率cupMobile.transaction.billAmount:convertRate
            // (13,MAC)16:// 账户1cupMobile.transaction.accountNumber1
            // (14)17:// 个人身份标识码cupMobile.transaction.pin
            // (MAC)20:// 原始交易提交时间cupMobile.transaction.origSubmitTime
            // (16,MAC)25:// 磁道2数据cupMobile.transaction.track2Data
            // (16,MAC)26:// 磁道3数据cupMobile.transaction.track3Data
            // 27:// 持卡人身份信息cupMobile.transaction.cardholderIdInfo
            // (MAC)28:// 终端芯片序列号cupMobile.transaction.cardSerialNumber
            // 29:// CMSP保留使用cupMobile.transaction.cmspReserved
            // 30:// 账户余额cupMobile.transaction.accountBalance
            // 31:// 账户余额币种cupMobile.transaction.accountBalance:currency
            // 32:// 电子钱包数据cupMobile.transaction.upCashData
            // (13,MAC)33:// 帐户2cupMobile.transaction.accountNumber2
            // (13,MAC)34:// 卡有效期cupMobile.transaction.expireDate
            // 35:// 服务信息cupMobile.transaction.serviceInfo
            // 36:// 动态密钥数据cupMobile.transaction.dynamicKeyData
            // 37:// 安全载体类型cupMobile.transaction.securityChipTp
            // 38:// SP代码cupMobile.transaction.spId
            // (MAC)39:// 卡片序列号cupMobile.transaction.ICNumber
            // 40:// 系统支持方cupMobile.transaction.SysProvide
            // 41:// 原交易流水号cupMobile.transaction.OrgTransSerNo
            // 42:// 信用卡账户余额cupMobile.transaction.creditAcctBal
            // 43:// 信用卡账户余额币种cupMobile.transaction.creditAcctBal:currency
            // (MAC)251:// 借贷记应用数据cupMobile.transaction.DCData
            // (MAC)252:// 商户摘要数据cupMobile.merchantAuthentication.digest
            // 253:// 商户数字签名cupMobile.merchantAuthentication.signature
            // 254:// 发送方数字签名cupMobile.senderSignature
            // 255:// 报文鉴别码cupMobile.mac

            LinkedHashMap<Integer, String> data = new LinkedHashMap<Integer, String>();
            Vector<String> macElements = new Vector<String>();
            for (Integer key : map.keySet())
            {
                String value = map.get(key);
                if (TextUtils.isEmpty(value))
                {
                    return null;
                }
                HPLog.i("getPlainMac", key + " : " + value);
                switch (key)
                {
                    case 4:// (MAC)交易提交时间cupMobile.transaction.submitTime
                    case 10:// (MAC)清算日期cupMobile.transaction.settleDate
                    case 20:// (MAC)原始交易提交时间cupMobile.transaction.origSubmitTime
                    case 28:// (MAC)终端芯片序列号cupMobile.transaction.cardSerialNumber
                    case 39:// (MAC)卡片序列号cupMobile.transaction.ICNumber
                    case 251:// (MAC)借贷记应用数据cupMobile.transaction.DCData
                    case 252:// (MAC)商户摘要数据cupMobile.merchantAuthentication.digest
                    case 16:// (13,MAC)账户1cupMobile.transaction.accountNumber1
                    case 33:// (13,MAC)帐户2cupMobile.transaction.accountNumber2
                    case 5:// (13,MAC)商户代码cupMobile.transaction.merchant:id
                    case 8:// (13,MAC)子商户/终端代码cupMobile.transaction.terminal:id
                    case 9:// (13,MAC)订单号cupMobile.transaction.order:id
                    case 11:// (13,MAC)交易金额cupMobile.transaction.transAmount
                    case 12:// (13,MAC)交易币种cupMobile.transaction.transAmount:currency
                    case 13:// (13,MAC)扣账金额cupMobile.transaction.billAmount
                    case 14:// (13,MAC)扣账币种cupMobile.transaction.billAmount:currency
                    case 15:// (13,MAC)扣账汇率cupMobile.transaction.billAmount:convertRate
                    case 34:// (13,MAC)卡有效期cupMobile.transaction.expireDate
                    case 25:// (16,MAC)磁道2数据cupMobile.transaction.track2Data
                        macElements.addElement(value);
                        break;
                    case 17:// (14)个人身份标识码cupMobile.transaction.pin
                        break;
                    case 26:// (16,MAC)磁道3数据cupMobile.transaction.track3Data
                        continue;
                }
                data.put(key, value);
            }
            // 计算MAC
            String macBlock = macBlock(macElements);
            HPLog.e("macBlock", macBlock);
            return macBlock;
        }
        catch (Exception e)
        {
            return null;
        }
    }
    /**
     * 组织MAC明文
     *
     * @param elements
     * @return
     */
    private static String macBlock(Vector<String> elements)
    {
        String mac_block = "";
        if (elements == null)
        {
            return mac_block;
        }
        int size = elements.size();
        for (int i = 0; i < size; i++)
        {
            String e = elements.elementAt(i);
            mac_block += e;
            if (i < size - 1)
            {
                mac_block += " ";
            }
        }
        mac_block = compressRepeatChar(mac_block, ' ');
        return mac_block;
    }
    /**
     * 去除多余的重复字符
     *
     * @param strOri
     * @param ch
     * @return
     */
    private static String compressRepeatChar(String strOri, char ch)
    {
        strOri = strOri.trim();
        StringBuffer resultBuffer = new StringBuffer();
        char[] ori_char = strOri.toCharArray();
        boolean first = true;
        for (int i = 0; i < ori_char.length; i++)
        {
            if (!first && ori_char[i] == ch)
            {
                continue;
            }
            first = (ori_char[i] != ch);
            resultBuffer.append(ori_char[i]);
        }
        return resultBuffer.toString();
    }
}
